[POC] Improve TypeScript Theme Components Performance #47013
+168
−37
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Important
Breaking Change: Deprecated type exports moved from
@mui/material/styles
to@mui/material/stylesDeprecated
Components
,ComponentsProps
,ComponentsOverrides
,ComponentsVariants
,adaptV4Theme
, or related types from@mui/material/styles
, moved to@mui/material/stylesDeprecated
.🎯 Main Purpose
Fix a severe TypeScript performance issue caused by circular type dependencies in the
ThemeOptions
andTheme
types.Components
imports all of components types from the library, causing massive type instantiation whencreateTheme()
is used.🔍 Problem & Solution Context
Components
type that import all components types and replace it with an empty interfaceThemeComponents
(user will need to augment this interface for autocompletion)adaptV4Theme
fromstyles
folder as it relying on theComponents
.CreateThemeComponent
utility type for declaring component theme typeThemeComponents
with built-in component theme type.With this change, perf improvement ~50% (see the result at the bottom)
🔧 Key Changes
Type System Overhaul
Components<Omit<Theme, 'components'>>
to simpleThemeComponents
interface increateThemeFoundation.ts:36
CreateThemeComponent<SlotNames, Props, OwnerState>
increateThemeNoVars.d.ts:98
for component-specific theme customizationButtonTheme
type inButton.d.ts:149
showing how other components should define their theme typesBreaking Changes
Components
,ComponentsProps
,ComponentsOverrides
, etc.) moved fromstyles/
to newstylesDeprecated/
folderstyles/index.d.ts:84
- users must now import from@mui/material/stylesDeprecated
styles
entry point (available in deprecated path)Migration
Recommended: selective theme components to optimize TypeScript
Preserve existing behavior: extend the
ThemeComponents
with the deprecatedComponents
Material UI as dependency (e.g. MUI X)
Update the
themeAugmentation.ts
to augment the@mui/material/stylesDeprecated
Backward Compatibility
mui-lab/src/themeAugmentation/*
files now import from and augment the deprecated modulestylesDeprecated
Performance Testing Infrastructure
packages/mui-material/perf-test/
with tooling to measure TypeScript performancetest-createTheme.ts:1
demonstrates the new pattern and allows measuring type instantiation costsREADME.md:1
provides comprehensive guide on running TypeScript diagnostics📁 Important Files to Review
packages/mui-material/src/styles/createThemeNoVars.d.ts:42
- Core type system changes that break the circular dependency. Review the simplifiedThemeComponents
type and newCreateThemeComponent
helper.packages/mui-material/src/styles/createThemeFoundation.ts:36
- NewThemeComponents
interface definition. Verify this simple interface provides sufficient flexibility.packages/mui-material/src/stylesDeprecated/
- All deprecated types moved here. Critical for ensuring backward compatibility works correctly, especially the module augmentation pattern.packages/mui-lab/src/themeAugmentation/components.ts:5
- Updated to import from deprecated path and augmentstylesDeprecated
module instead ofstyles
. Validates the backward compatibility strategy.📋 Complete File Changes
Core Type System:
src/styles/createTheme.ts
- Added exports for new typessrc/styles/createThemeFoundation.ts
- AddedThemeComponents
interfacesrc/styles/createThemeNoVars.d.ts
- Replaced circular type, addedCreateThemeComponent
src/styles/createThemeWithVars.d.ts
- Removed redundant components overridesrc/styles/useThemeProps.d.ts
- Updated to useThemeComponents
src/styles/index.d.ts
- Removed deprecated exports, added new type exportssrc/styles/index.js
- RemovedadaptV4Theme
exportDeprecated Types (moved to stylesDeprecated/):
adaptV4Theme.d.ts
,adaptV4Theme.js
,adaptV4Theme.test.js
components.ts
,overrides.ts
,props.ts
,variants.ts
index.ts
(new) - Re-exports all deprecated typesComponent Updates:
src/Button/Button.d.ts
- AddedButtonTheme
export as example patternsrc/DefaultPropsProvider/DefaultPropsProvider.tsx
- Updated import pathsrc/locale/utils/LocaleTextApi.ts
- Updated import pathMUI Lab Updates:
mui-lab/src/themeAugmentation/components.ts
- Import from deprecated pathmui-lab/src/themeAugmentation/overrides.ts
- Import from deprecated pathmui-lab/src/themeAugmentation/props.ts
- Import from deprecated pathDocumentation Theme:
mui-docs/src/branding/brandingTheme.ts
- ExtendsThemeComponents
with deprecatedComponents<Theme>
Performance Testing:
perf-test/README.md
- Guide for running TypeScript performance diagnosticsperf-test/test-createTheme.ts
- Test case for measuring type instantiationperf-test/tsconfig.json
- TypeScript configuration for perf testing🚀 Impact
Performance Improvements:
Developer Experience:
Migration Required:
@mui/material/styles
need to update imports to@mui/material/stylesDeprecated
CreateThemeComponent
pattern for component customization💡 Implementation Notes
The key insight here is separating concerns: instead of having one massive recursive generic type that handles all components, each component can define its own theme type using the
CreateThemeComponent
helper. This makes TypeScript's job much easier since it doesn't have to recursively expand a generic type for every component.The
ButtonTheme
example shows the pattern:This pattern scales linearly rather than exponentially, which is why it's so much more performant.
Note
The perf-test folder provides tooling to measure the impact of these changes. Run
npx tsc --diagnostics
in that folder to see type instantiation counts and memory usage.Result
Before:
After:
Test
Follow the packages/mui-material/perf-test/README.md to test this PR.